home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / misc / emu / p-interp.lha / p-interp-0.4 / Diskio.c < prev    next >
C/C++ Source or Header  |  2001-06-07  |  6KB  |  295 lines

  1. /*
  2.  
  3.   P-Code interpreter (to run the apple pascal system)
  4.   Copyright (C) 2000 Mario Klebsch
  5.  
  6.   This program is free software; you can redistribute it and/or modify
  7.   it under the terms of the GNU General Public License as published by
  8.   the Free Software Foundation; either version 2 of the License, or
  9.   (at your option) any later version.
  10.  
  11.   This program is distributed in the hope that it will be useful,
  12.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.   GNU General Public License for more details.
  15.  
  16.   You should have received a copy of the GNU General Public License
  17.   along with this program; if not, write to the Free Software
  18.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.   $Log: Diskio.c,v $
  21.   Revision 1.5  2001/06/07 19:57:53  mario
  22.   Implementierung vom Diskettenzugriff mittels read(), write() & lseek()
  23.   um Systeme ohne mmap() zu unterstützen.
  24.  
  25.   Revision 1.4  2001/05/26 15:13:29  mario
  26.   Diverse kleine Fehler behoben, fehlende #includes, Labels ohne Statement
  27.   dahinter, ...
  28.  
  29.   Revision 1.3  2001/05/21 19:06:48  mario
  30.   Mode-Parameter bei den Disk-IO-Routinen entfernt
  31.  
  32.   Revision 1.2  2001/05/20 13:12:02  mario
  33.   CVS-Idents und Logs eingefügt
  34.  
  35.  
  36. */
  37.  
  38. #ident "$Id: Diskio.c,v 1.5 2001/06/07 19:57:53 mario Exp $";
  39.  
  40. #include <unistd.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <fcntl.h>
  44. #include <assert.h>
  45. #include <string.h>
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #ifdef USE_MMAP
  49. #include <sys/mman.h>
  50. #endif
  51.  
  52. #include "psystem.h"
  53. #include "Memory.h"
  54. #include "Diskio.h"
  55.  
  56. static int DskTable[16]={0,14,13,12,11,10,9,8,7,6,5,4,3,2,1,15};
  57.  
  58. static struct Unit
  59. {
  60.   int        Fd;
  61.   byte        *Data;
  62.   size_t    Size;
  63.   int        RdOnly;
  64.   int        *Translate;
  65. } Units[MAX_UNIT];
  66.  
  67. void DiskRead(word Unit, word Addr, Integer AddrOffset,
  68.           word Len, word BlockNo)
  69. {
  70.   int        i;
  71.   size_t    Offset = BlockNo*512;
  72.   int        Track  = BlockNo/8;
  73.   int        Sector = (BlockNo&7)*2;
  74.   struct Unit *u;
  75.  
  76.   assert(Unit<MAX_UNIT);
  77.   u=&Units[Unit];
  78.   if ( (u->Fd<0) && !u->Data )
  79.     {
  80.       IoError(9);
  81.       return;
  82.     }
  83.   if ((Offset+Len)>u->Size)
  84.     {
  85.       IoError(64);
  86.       return;
  87.     }
  88.  
  89.   while (Len)
  90.     {
  91.       int Size=256;
  92.       int Sec=Sector;
  93.       if (Len<Size)
  94.     Size=Len;
  95.       if (u->Translate)
  96.     Sec=u->Translate[Sector];
  97.       if (u->Data)
  98.     for (i=0; i<Size; i++)
  99.       MemWrByte(Addr, AddrOffset+i,
  100.             u->Data[(Track*16+Sec)*256+i]);
  101.       else
  102.     {
  103.       char Buf[256];
  104.       if ( (lseek(u->Fd, (Track*16+Sec)*256, SEEK_SET) <0) ||
  105.            ( read(u->Fd, Buf, Size) != Size) )
  106.         {
  107.           IoError(64);
  108.           return;
  109.         }
  110.       for (i=0; i<Size; i++)
  111.         MemWrByte(Addr, AddrOffset+i, Buf[i] );
  112.     }
  113.       AddrOffset +=Size;
  114.       Len-=Size;
  115.       Sector++;
  116.       if (Sector>=16)
  117.     {
  118.       Track++;
  119.       Sector=0;
  120.     }
  121.     }
  122.   IoError(0);
  123. }
  124.  
  125. void DiskWrite(word Unit, word Addr, Integer AddrOffset,
  126.            word Len, word BlockNo)
  127. {
  128.   int        i;
  129.   size_t    Offset = BlockNo*512;
  130.   int        Track  = BlockNo/8;
  131.   int        Sector = (BlockNo&7)*2;
  132.   struct Unit *u;
  133.  
  134.   assert(Unit<MAX_UNIT);
  135.   u=&Units[Unit];
  136.   if ( (u->Fd<0) && !u->Data )
  137.     {
  138.       IoError(9);
  139.       return;
  140.     }
  141.   else if (u->RdOnly)
  142.     {
  143.       IoError(16);
  144.       return;
  145.     }
  146.   else if ((Offset+Len)>u->Size)
  147.     {
  148.       IoError(64);
  149.       return;
  150.     }
  151.  
  152.   while (Len)
  153.     {
  154.       int Size=256;
  155.       int Sec=Sector;
  156.       if (Len<Size)
  157.     Size=Len;
  158.       if (u->Translate)
  159.     Sec=u->Translate[Sector];
  160.       if (u->Data)
  161.     for (i=0; i<Size; i++)
  162.       u->Data[(Track*16+Sec)*256+i] =
  163.         MemRdByte(Addr, AddrOffset+i );
  164.     else
  165.       {
  166.         char Buf[256];
  167.         for (i=0; i<Size; i++)
  168.           Buf[i] =    MemRdByte(Addr, AddrOffset+i );
  169.         if ( (lseek(u->Fd, (Track*16+Sec)*256, SEEK_SET) <0) ||
  170.          ( write(u->Fd, Buf, Size) != Size) )
  171.           {
  172.         IoError(64);
  173.         return;
  174.           }
  175.       }
  176.       AddrOffset +=Size;
  177.       Len-=Size;
  178.       Sector++;
  179.       if (Sector>=16)
  180.     {
  181.       Track++;
  182.       Sector=0;
  183.     }
  184.     }
  185.   IoError(0);
  186. }
  187.  
  188. void DiskClear(word Unit)
  189. {
  190.   assert(Unit<MAX_UNIT);
  191.   IoError(0);
  192. }
  193.  
  194. void DiskStat(word Unit)
  195. {
  196.   struct Unit *u;
  197.  
  198.   assert(Unit<MAX_UNIT);
  199.   u=&Units[Unit];
  200.   if ( (u->Fd<0) && !u->Data )
  201.     IoError(9);
  202.   else
  203.     IoError(0);
  204. }
  205.  
  206. void DiskUmount(word Unit)
  207. {
  208.   struct Unit *u;
  209.  
  210.   assert(Unit<MAX_UNIT);
  211.   u=&Units[Unit];
  212.   if (u->Data)
  213.     {
  214. #ifdef USE_MMAP
  215.       munmap(u->Data, u->Size);
  216. #else
  217.       free(u->Data);
  218. #endif
  219.       u->Data=NULL;
  220.     }
  221.   if (u->Fd>=0)
  222.     {
  223.       close(u->Fd);
  224.       u->Fd=-1;
  225.     }
  226. }
  227.  
  228. int DiskMount(word Unit, const char *FileName, enum DiskMode Mode)
  229. {
  230.   int    fd;
  231.   struct stat buf;
  232.   struct Unit *u;
  233.  
  234.   assert(Unit<MAX_UNIT);
  235.   u=&Units[Unit];
  236.   if ((fd=open(FileName,(Mode==ReadWrite)?O_RDWR:O_RDONLY))<0)
  237.     {
  238.       perror(FileName);
  239.       return(-1);
  240.     }
  241.   if (fstat(fd, &buf)<0)
  242.     {
  243.       perror(FileName);
  244.       close(fd);
  245.       return(-1);
  246.     }
  247.   DiskUmount(Unit);
  248.  
  249.   u->Fd=fd;
  250.   u->Size=buf.st_size;
  251.   u->RdOnly=(Mode==ReadOnly);
  252.   u->Translate=NULL;
  253.  
  254.   if ( (strlen(FileName)>4) &&
  255.        (strcmp(FileName+strlen(FileName)-4,".dsk")==0) )
  256.     u->Translate=DskTable;
  257. #ifdef USE_MMAP
  258.   u->Data=mmap(NULL, u->Size,
  259.            (Mode==ReadOnly)?PROT_READ:PROT_READ|PROT_WRITE,
  260.            (Mode==Forget)?MAP_PRIVATE:MAP_SHARED,
  261.            u->Fd, 0);
  262.   close(Unit[Unit].Fd);
  263.   Unit[Unit].Fd=-1;
  264. #else
  265.   if (Mode==Forget)
  266.     {
  267.       u->Data=malloc(u->Size);
  268.       assert(u->Data);
  269.       if (read(u->Fd,u->Data,u->Size) !=
  270.       u->Size)
  271.     {
  272.       perror(FileName);
  273.       free(u->Data);
  274.       u->Data=NULL;
  275.       close(u->Fd);
  276.       u->Fd=-1;
  277.       return(-1);
  278.     }
  279.       close(u->Fd);
  280.       u->Fd=-1;
  281.     }
  282. #endif
  283.   return(0);
  284. }
  285.  
  286. void DiskInit(void)
  287. {
  288.   int i;
  289.   for (i=0; i<MAX_UNIT; i++)
  290.     {
  291.       Units[i].Data=NULL;
  292.       Units[i].Fd=-1;
  293.     }
  294. }
  295.